<template>
    <div class="edit-avatar-container unselect" :draggable="false">
        <el-dialog v-model="modelValue" width="800px" append-to-body @closed="closeDialog" destroy-on-close
            @open="openDialog" class="unselect edit-avatar-container">
            <template #header>
                <span class="unselect">{{ title }}</span>
            </template>
            <div style="height: 300px;position: relative;background: rgba(0, 0, 0, 0.02);"
                class="animate__animated animate__zoomIn animate__fast">
                <VueCropper ref="cropperRef" :img="options.img" info :autoCrop="options.autoCrop" fixed
                    class="cursor-pointer" :autoCropWidth="options.autoCropWidth" original infoTrue
                    :autoCropHeight="options.autoCropHeight" :fixedBox="options.fixedBox" centerBox
                    :outputType="options.outputType" @realTime="realTime" limitMinSize="100" />
                <div class="preview-box flex-display-center unselect">
                    <img v-if="previews.url" :src="previews.url" style="width:100%;height:100%" :draggable="false"
                        @load="handleImageLoaded" />
                </div>
            </div>
            <div class="btn-box">
                <div class="file-button cursor-pointer unselect" @click="open">选择文件</div>
                <div style="display: inline-flex;gap: 10px;justify-content: flex-end;">
                    <div class="file-button is-circle cursor-pointer" @click="changeScale(1)">
                        <el-icon>
                            <Plus />
                        </el-icon>
                    </div>
                    <div class="file-button is-circle cursor-pointer" @click="changeScale(-1)">
                        <el-icon>
                            <Minus />
                        </el-icon>
                    </div>
                    <div class="file-button is-circle cursor-pointer" @click="rotateLeft">
                        <el-icon>
                            <RefreshLeft />
                        </el-icon>
                    </div>
                    <div class="file-button is-circle cursor-pointer" @click="rotateRight">
                        <el-icon>
                            <RefreshRight />
                        </el-icon>
                    </div>
                </div>
                <div class="file-button cursor-pointer unselect" @click="determine" v-limitClick>提 交</div>
            </div>
        </el-dialog>
    </div>
</template>

<script setup>
import { Plus, Minus, RefreshLeft, RefreshRight } from "@element-plus/icons-vue"
import "vue-cropper/dist/index.css"
import { VueCropper } from "vue-cropper"
import { ref, reactive } from "vue"
import { useFile, useElMessage } from '@usehook'

const emit = defineEmits(["complete"])
const props = defineProps({
    title: {
        type: String,
        default: "上传图片",
    },
    image: {
        type: String,
        default: "",
    },
})

const loaded = ref(false)

const { open } = useFile({
    types: [{
        description: 'image',
        accept: {
            'image/*': [],
        },
    }],
    excludeAcceptAllOption: true,
    onSuccess: (file) => {
        const fileURL = URL.createObjectURL(file)
        // 图片在这里
        const image = new Image()
        image.src = fileURL
        image.onload = () => {
            const width = image.width
            const height = image.height
            if (width < 100 || height < 100) {
                useElMessage.error("图片" + width + "x" + height + ", 宽高至少100像素, 请重新选择")
            } else {
                options.img = fileURL
            }
        }
    }
})

const cropperRef = ref(null)

const modelValue = defineModel({ default: false })

// cropper配置  更多配置可参考 https://www.npmjs.com/package/vue-cropper
const options = reactive({
    img: "", // 裁剪图片的地址
    autoCropWidth: 200, // 默认生成截图框宽度 默认容器的 80%
    autoCropHeight: 200, // 默认生成截图框高度 默认容器的 80%
    outputType: "png", // 裁剪生成图片的格式 jpeg, png, webp
    autoCrop: true, // 是否默认生成截图框
    fixedBox: false, // 固定截图框大小
});
const previews = ref({
    url: "",
})

const openDialog = () => {
    if (props.image) options.img = props.image
}

// 修改图片大小 正数为变大 负数变小
const changeScale = (num) => {
    num = num || 1;
    cropperRef.value.changeScale(num)
}
// 向左边旋转90度
const rotateLeft = () => {
    cropperRef.value.rotateLeft()
}
// 向右边旋转90度
const rotateRight = () => {
    cropperRef.value.rotateRight()
}

// 实时预览事件
const realTime = () => {
    cropperRef.value.getCropData(data => {
        if (previews.value.url !== data && data.toString() !== "") {
            previews.value.url = data
        }
    })
}

// 关闭弹窗
const closeDialog = () => {
    options.img = ""
    previews.value.url = ""
    modelValue.value = false
}
// 提交图片
const determine = () => {
    emit("complete", previews.value.url)
    closeDialog()
}

const handleImageLoaded = () => {
    loaded.value = true
}
</script>

<style lang="scss">
.edit-avatar-container .img-box {
    border-radius: 50%;
    border: 1px solid rgb(204 204 204 / 30%);
    width: 10vw;
    height: 10vw;
}

.edit-avatar-container.unselect {
    -moz-user-select: none !important;
    /*火狐*/
    -webkit-user-select: none !important;
    /*webkit浏览器*/
    -ms-user-select: none !important;
    /*IE10*/
    -khtml-user-select: none !important;
    /*早期浏览器*/
    user-select: none !important;
}

.edit-avatar-container .preview-box {
    position: absolute;
    top: 1px;
    right: 1px;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    border: 1px solid rgb(204 204 204 / 30%);
    overflow: hidden;
}

.edit-avatar-container .vue-cropper {
    background-image: none;
    border: 1px solid rgb(204 204 204 / 30%);
    border-radius: 3px;

    .cropper-modal {
        background: transparent;
    }
}

.edit-avatar-container .file-button {
    background: fixed linear-gradient(to right, #a2b8ff, #5087ff);
    color: aliceblue;
    width: 70px;
    height: 25px;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 5px;
    border-radius: 3px;
}

.edit-avatar-container .file-button.is-circle {
    border-radius: 50%;
    height: 25px;
    width: 25px;
}

.edit-avatar-container .btn-box {
    margin-top: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
</style>